use std::{env, fs};
mod lexer;
use crate::lexer::{tokenize, LexerError, Token};

fn main() {
    let args: Vec<String> = env::args().collect();

    if args.len() < 2 {
        eprintln!("Usage: {} <filename>", args[0]);
        std::process::exit(1);
    }

    let filename = &args[1];
    
    let input = fs::read_to_string(filename)
        .unwrap_or_else(|e| {
            eprintln!("Failed to read file {}: {}", filename, e);
            std::process::exit(1);
        });

    match tokenize(&input) {
        Ok(tokens) => {
            for (token, text, line) in tokens {
                let token_type = match token {
                    Token::Const => "CONST",
                    Token::Int => "INT",
                    Token::Void => "VOID",
                    Token::If => "IF",
                    Token::Else => "ELSE",
                    Token::While => "WHILE",
                    Token::Break => "BREAK",
                    Token::Continue => "CONTINUE",
                    Token::Return => "RETURN",
                    Token::Plus => "PLUS",
                    Token::Minus => "MINUS",
                    Token::Mul => "MUL",
                    Token::Div => "DIV",
                    Token::Mod => "MOD",
                    Token::Assign => "ASSIGN",
                    Token::Eq => "EQ",
                    Token::Neq => "NEQ",
                    Token::Lt => "LT",
                    Token::Gt => "GT",
                    Token::Le => "LE",
                    Token::Ge => "GE",
                    Token::Not => "NOT",
                    Token::And => "AND",
                    Token::Or => "OR",
                    Token::LParen => "L_PAREN",
                    Token::RParen => "R_PAREN",
                    Token::LBrace => "L_BRACE",
                    Token::RBrace => "R_BRACE",
                    Token::LBrackt => "L_BRACKT",
                    Token::RBrackt => "R_BRACKT",
                    Token::Comma => "COMMA",
                    Token::Semicolon => "SEMICOLON",
                    Token::Ident(_) => "IDENT",
                    Token::Integer(_) => "INTEGER_CONST",
                };
                
                eprintln!("{} {} at Line {}.", token_type, text, line);
            }
        }
        Err(errors) => {
            for error in errors {
                match error {
                    LexerError::ParseError(msg, line) => {
                        eprintln!("Error type A at Line {}: {}", line, msg);
                    }
                }
            }
            std::process::exit(1);
        }
    }
}